package com.wust.modules.online.config.service.impl;

import com.wust.modules.online.config.exception.DBException;
import com.wust.modules.online.config.service.DbTableHandle;
import com.wust.modules.online.config.util.ColumnMeta;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;

/**
 * @author wanheng
 */
@NoArgsConstructor
public class POSTGRESQLDbTableHandle implements DbTableHandle {


    @Override
    public String getAddColumnSql(ColumnMeta columnMeta) {
        return " ADD COLUMN " + this.getCreateSql(columnMeta) + ";";
    }

    @Override
    public String getReNameFieldName(ColumnMeta columnMeta) {
        return " RENAME  COLUMN  " + columnMeta.getOldColumnName() + " to " + columnMeta.getColumnName() + ";";
    }

    @Override
    public String getUpdateColumnSql(ColumnMeta cgformcolumnMeta, ColumnMeta datacolumnMeta) throws DBException {
        return "  ALTER  COLUMN   " + this.getCreateSql(cgformcolumnMeta, datacolumnMeta) + ";";
    }

    @Override
    public String getSpecialHandle(ColumnMeta cgformcolumnMeta, ColumnMeta datacolumnMeta) {
        return "  ALTER  COLUMN   " + this.getUpdateSql(cgformcolumnMeta, datacolumnMeta) + ";";
    }

    @Override
    public String getMatchClassTypeByDataType(String dataType, int digits) {
        String type = "";
        if ("varchar".equalsIgnoreCase(dataType)) {
            type = "string";
        } else if ("double".equalsIgnoreCase(dataType)) {
            type = "double";
        } else if (dataType.contains("int")) {
            type = "int";
        } else if ("Date".equalsIgnoreCase(dataType)) {
            type = "date";
        } else if ("timestamp".equalsIgnoreCase(dataType)) {
            type = "date";
        } else if ("bytea".equalsIgnoreCase(dataType)) {
            type = "blob";
        } else if ("text".equalsIgnoreCase(dataType)) {
            type = "text";
        } else if ("decimal".equalsIgnoreCase(dataType)) {
            type = "bigdecimal";
        } else if ("numeric".equalsIgnoreCase(dataType)) {
            type = "bigdecimal";
        }

        return type;
    }

    @Override
    public String dropTableSql(String tableName) {
        return " DROP TABLE  " + tableName + " ;";
    }

    @Override
    public String getDropColumnSql(String fieldName) {
        return " DROP COLUMN " + fieldName + ";";
    }

    private String getCreateSql(ColumnMeta columnMeta, ColumnMeta columnMeta2) throws DBException {
        String sql = "";
        if ("string".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + "  type character varying(" + columnMeta.getColumnSize() + ") ";
        } else if ("date".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + "  type timestamp ";
        } else if ("int".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " type int4 ";
        } else if ("double".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " type  numeric(" + columnMeta.getColumnSize() + "," + columnMeta.getDecimalDigits() + ") ";
        } else if ("BigDecimal".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " type  decimal(" + columnMeta.getColumnSize() + "," + columnMeta.getDecimalDigits() + ") ";
        } else if ("text".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " text ";
        } else if ("blob".equalsIgnoreCase(columnMeta.getColunmType())) {
            throw new DBException("blob类型不可修改");
        }

        return sql;
    }

    private String getUpdateSql(ColumnMeta columnMeta1, ColumnMeta columnMeta2) {
        String sql = "";
        if (columnMeta1.isEqual(columnMeta2)) {
            if ("string".equalsIgnoreCase(columnMeta1.getColunmType())) {
                sql = columnMeta1.getColumnName();
                sql = sql + (StringUtils.isNotEmpty(columnMeta1.getFieldDefault()) ? " SET DEFAULT " + columnMeta1.getFieldDefault() : " DROP DEFAULT");
            } else if ("date".equalsIgnoreCase(columnMeta1.getColunmType())) {
                sql = columnMeta1.getColumnName();
                sql = sql + (StringUtils.isNotEmpty(columnMeta1.getFieldDefault()) ? " SET DEFAULT " + columnMeta1.getFieldDefault() : " DROP DEFAULT");
            } else if ("int".equalsIgnoreCase(columnMeta1.getColunmType())) {
                sql = columnMeta1.getColumnName();
                sql = sql + (StringUtils.isNotEmpty(columnMeta1.getFieldDefault()) ? " SET DEFAULT " + columnMeta1.getFieldDefault() : " DROP DEFAULT");
            } else if ("double".equalsIgnoreCase(columnMeta1.getColunmType())) {
                sql = columnMeta1.getColumnName();
                sql = sql + (StringUtils.isNotEmpty(columnMeta1.getFieldDefault()) ? " SET DEFAULT " + columnMeta1.getFieldDefault() : " DROP DEFAULT");
            } else if ("bigdecimal".equalsIgnoreCase(columnMeta1.getColunmType())) {
                sql = columnMeta1.getColumnName();
                sql = sql + (StringUtils.isNotEmpty(columnMeta1.getFieldDefault()) ? " SET DEFAULT " + columnMeta1.getFieldDefault() : " DROP DEFAULT");
            } else if ("text".equalsIgnoreCase(columnMeta1.getColunmType())) {
                sql = columnMeta1.getColumnName();
                sql = sql + (StringUtils.isNotEmpty(columnMeta1.getFieldDefault()) ? " SET DEFAULT " + columnMeta1.getFieldDefault() : " DROP DEFAULT");
            }
        }

        return sql;
    }

    private String getCreateSql(ColumnMeta columnMeta) {
        String sql = "";
        if ("string".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " character varying(" + columnMeta.getColumnSize() + ") ";
        } else if ("date".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " timestamp ";
        } else if ("int".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " int4";
        } else if ("double".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " numeric(" + columnMeta.getColumnSize() + "," + columnMeta.getDecimalDigits() + ") ";
        } else if ("bigdecimal".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " decimal(" + columnMeta.getColumnSize() + "," + columnMeta.getDecimalDigits() + ") ";
        } else if ("blob".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " bytea(" + columnMeta.getColumnSize() + ") ";
        } else if ("text".equalsIgnoreCase(columnMeta.getColunmType())) {
            sql = columnMeta.getColumnName() + " text ";
        }

        sql = sql + (StringUtils.isNotEmpty(columnMeta.getFieldDefault()) ? " DEFAULT " + columnMeta.getFieldDefault() : " ");
        return sql;
    }


    @Override
    public String getCommentSql(ColumnMeta columnMeta) {
        return "COMMENT ON COLUMN " + columnMeta.getTableName() + "." + columnMeta.getColumnName() + " IS '" + columnMeta.getComment() + "'";
    }

    @Override
    public String dropIndexs(String indexName, String tableName) {
        return "DROP INDEX " + indexName;
    }

    @Override
    public String countIndex(String indexName, String tableName) {
        return "SELECT count(*) FROM pg_indexes WHERE indexname = '" + indexName + "' and tablename = '" + tableName + "'";
    }
}
